﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Drawing;
using System.Data;
using System.Linq;
using System.Text;
using System.Windows.Forms;
using System.Security.Cryptography;
using System.Runtime.InteropServices;
using System.IO;
using System.Net;
using System.Threading;
using System.Reflection;
using mshtml;

namespace FileUpManage
{
    [Guid("0A049261-8592-494D-8AAE-0787B3E14153")]
    public partial class FileManageClient : UserControl, IObjectSafety
    {
        private long transport;//已经上传文件大小
        private long filelenght;
        private IHTMLWindow2 htmlWin;//调用页面的文档
        private string Jsfunc; //页面的JS函数 
        private FTPClient branchftp = null;//上传分店的FTP客户端
        private FTPClient headftp = null;//上传至总店FTP客户端
        private string fileFullName;//文件上传的绝对路径 
        private string previewfullName;//上传缩略图的绝对路径
        private string strsuffix;//文件后缀名
        private string fileName;//文件名
        private string previewName;//缩略图文件名
        private string previewsuffix;//缩略图后缀名
        public string fileguid;
        private string title;
        private string strGIud;
        public string fileguid_branch;
        public int flag;//判断该上传文件类型 0表示图片文件 1表示视频文件
        private bool ishead;//判断是否是总店在进行上传操作
        private int userid; //用户ID
        private string username;//用户名
        private string password;//用户密码
        private int branchid;//分店编号
        private string NAS_IP;//分店Nas的IP
        private string NAS_USERNAME; //分店Nas的用户名
        private string NAS_PASSWORD; //分店Nas的密码
        private string HEAD_NAS_IP; //总店Nas的IP
        private string HEAD_NAS_USERNAME; //总店Nas的用户名
        private string HEAD_NAS_PASSWORD; //总店Nas的密码
        private string ImageURL;//图片存储二级地址
        private string VideoURL;//视频存储二级地址
        public bool IsUpload = false; //是否正在上传
        public bool IsSucceed = false;//上传是否成功

        public FileManageClient()
        {
            InitializeComponent();
        }

        #region 获取用户FTP参数
        private void GetParameter(string name, string password)
        {
            WebLoginClient loginserver = new WebLoginClient();
            string[] arry = new string[4];
            arry = loginserver.UserLogin(name, password).ToArray();
            if (arry[0] == "1")
            {
                userid = Convert.ToInt32(arry[1].ToString());
                username = arry[2].ToString();
                this.password = password;
                branchid = Convert.ToInt32(arry[3].ToString());
                NAS_IP = arry[4].ToString();
                if (NAS_IP.IndexOf("/") != -1)
                {
                    NAS_IP = NAS_IP.Substring(0, NAS_IP.IndexOf("/"));
                }
                NAS_USERNAME = arry[5].ToString();
                NAS_PASSWORD = arry[6].ToString();
                HEAD_NAS_IP = arry[7].ToString();
                HEAD_NAS_USERNAME = arry[8].ToString();
                HEAD_NAS_PASSWORD = arry[9].ToString();
                ImageURL = arry[10].ToString();
                VideoURL = arry[11].ToString();
                if (NAS_IP == HEAD_NAS_IP)
                {
                    ishead = true;
                }
                else
                {
                    ishead = false;
                }
            }
        }
        #endregion


        #region 获取上传文件进度
        public string GetProgress()
        {
            string strProgress = "";
            long intervalTransfer = 0;
            strProgress += fileFullName + "|";
            if (IsUpload)
            {
                strProgress += "1|";
            }
            else
            {
                strProgress += "0|";
            }
            if (IsSucceed)
            {
                strProgress += "1|";
            }
            else
            {
                strProgress += "0|";
            }
            strProgress += (filelenght / 1048576).ToString() + "|";
            if (IsUpload)
            {
                intervalTransfer = headftp.HaveTransfer - transport;//当前间隔传送大小
                if (intervalTransfer != 0)
                {
                    transport += intervalTransfer;//已经传送大小
                    //strProgress += ((transport / filelenght) * 100).ToString() + "|";//已传送百分比
                    strProgress += (transport / 1048576) + "|";
                    strProgress += (intervalTransfer / 1024).ToString() + "|";//上传速度
                    strProgress += ((filelenght - transport) / (intervalTransfer) + 1).ToString() + "|";//剩余时间
                    strProgress += (((double)transport / filelenght) * 100).ToString();//已传送百分比
                }
                else
                {
                    strProgress += (transport / 1048576) + "|";//已传送百分比
                    strProgress += "0|";
                    strProgress += "稍等下...|";
                    strProgress += (((double)transport / filelenght) * 100).ToString();//已传送百分比
                }
            }
            return strProgress;
        }
        #endregion

        public void CancelUpload()
        {
            if (IsUpload == true)
            {
                if (ishead)
                {
                    if (flag == 1)
                    {
                        headftp.ChDir(VideoURL);
                    }
                    else if (flag == 0)
                    {
                        headftp.ChDir(ImageURL);
                    }
                    headftp.Delete(fileguid);
                }
                else
                {
                    if (flag == 1)
                    {
                        branchftp.ChDir(VideoURL);
                        headftp.ChDir(VideoURL);
                    }
                    else if (flag == 0)
                    {
                        branchftp.ChDir(ImageURL);
                        headftp.ChDir(ImageURL);
                    }
                    headftp.Delete(fileguid); //上传文件
                    branchftp.Delete(fileguid);
                }
            }
        }

        public string SayHello()
        {
            return "Hello, now is " + DateTime.Now.ToString();
        }

        #region //调用页面js
        private void CallJavaScript()
        {
            try
            {
                //调用JavaScript方法OnScaned并传递参数，因为此方法可能并没有在页面中实现，所以要进行异常处理
                htmlWin.GetType().InvokeMember(Jsfunc, BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, htmlWin, new object[] { "参数" });
            }
            catch { }
        }


        //public void SetFunc(object win, string func)
        //{
        //    IHTMLWindow2 htmlWin = (win as IHTMLWindow2);
        //    if (htmlWin == null || string.IsNullOrEmpty(func))
        //    {
        //        MessageBox.Show("赋值错误。");
        //    }
        //    else
        //    {
        //        //以下是调用方法，由于仅仅是示例，所以直接放在SetFunc方法中了。实际开发中，大家根据情况放到相应地方。 
        //        //这里调用的方法我提供了两种：1，反射的方法；2，JS代码语法。 
        //        //大家可以根据自己熟悉的情况采用适合自己的方法。两种方法的效果都是一样的。 


        //        //方法1。 
        //        htmlWin.GetType().InvokeMember(func, BindingFlags.Instance | BindingFlags.InvokeMethod | BindingFlags.Public, null, htmlWin, new object[] { "参数" });

        //        //方法2。 
        //        //string jsCode = string.Format("{0}('{1}')", func, "参数");
        //        //htmlWin.execScript(jsCode, "jscript");


        //    }
        //}
        #endregion


        #region 上传文件接口
        public void UploadFile(string filepath, string type, string prefilepath, string username, string password, string filetitel, object win, string func)
        {
            try
            {
                GetParameter(username, password);
            }
            catch (Exception ex)
            {
                fileguid = "0" + ex.Message;
                IsSucceed = false;
                IsUpload = false;
                return;
            }
            htmlWin = (win as IHTMLWindow2);
            Jsfunc = func;
            fileFullName = filepath;
            flag = Convert.ToInt32(type);
            previewfullName = prefilepath;
            title = filetitel;
            FileInfo fi = new FileInfo(fileFullName);
            filelenght = fi.Length;
            //CallJavaScript();
            //System.Threading.Timer aTimer = new System.Threading.Timer(new System.Threading.TimerCallback(CallJavaScript), null, 0, 500);
            if (ValidateFile(fileFullName, previewfullName))
            {
                if (!IsUpload)
                {
                    IsUpload = true;
                    try
                    {
                        Thread upThread = new Thread(UpFile);
                        upThread.Start();
                    }
                    catch (Exception ex)
                    {
                        fileguid = "-1" + ex.Message;
                        IsSucceed = false;
                        IsUpload = false;
                        return;
                    }
                }
            }
        }
        #endregion

        #region 文件验证操作
        private bool ValidateFile(string file_FullName, string preview_fullName)
        {
            this.fileFullName = file_FullName;
            this.previewfullName = preview_fullName;
            fileName = fileFullName.Substring(fileFullName.LastIndexOf(@"\") + 1);//文件名
            strsuffix = fileName.Substring(fileName.LastIndexOf(".") + 1).ToLower();//文件后缀名
            //判断是否选择文件
            if (string.IsNullOrEmpty(fileFullName))
            {
                //throw new IOException("请选择一个要上传的文件!");
                return false;
            }
            //判断可执行文件
            if (strsuffix == "exe" || strsuffix == "bat" || strsuffix == "sys" || strsuffix == "com")
            {
                //throw new IOException("不能上传可执行文件!");
                return false;
            }
            //上传视频时要同时上传预览图片
            if (flag == 1)
            {
                previewName = previewfullName.Substring(previewfullName.LastIndexOf(@"\") + 1);//预览图片文件名
                previewsuffix = previewName.Substring(previewName.LastIndexOf(".") + 1).ToLower();//预览图片文件后缀名
                //判断是否选择预览图片
                if (string.IsNullOrEmpty(previewfullName))
                {
                    //throw new IOException("请选择一个要上传的预览图片!");
                    return false;
                }
                //判断上传的是否为图片
                if (previewsuffix != "jpg" && previewsuffix != "bmp" && previewsuffix != "gif" && previewsuffix != "png")
                {
                    //throw new IOException("请上传图片文件!");
                    return false;
                }
                //判断上传的是否为视频
                if (strsuffix != "flv" && strsuffix != "wmv" && strsuffix != "mp4" && strsuffix != "avi" && strsuffix != "rmvb" && strsuffix != "f4v" && strsuffix != "mov")
                {
                    //throw new IOException("请上传视频文件!");
                    return false;
                }
            }
            //上传图片
            if (flag == 0)
            {
                if (strsuffix != "jpg" && strsuffix != "bmp" && strsuffix != "gif" && strsuffix != "png")
                {
                    //throw new IOException("请上传图片文件!");
                    return false;
                }
            }
            return true;
        }
        #endregion

        #region 上传文件
        private void UpFile()
        {
            strGIud = System.Guid.NewGuid().ToString();
            fileguid_branch = strGIud + "-" + branchid;
            fileguid = strGIud + "." + strsuffix;
            if (!ishead)
            {
                try
                {
                    branchftp = new FTPClient(NAS_IP, "", NAS_USERNAME, NAS_PASSWORD, 21);//分店FTP
                    headftp = new FTPClient(HEAD_NAS_IP, "", HEAD_NAS_USERNAME, HEAD_NAS_PASSWORD, 21);//总店FTP
                    if (flag == 1)
                    {
                        branchftp.ChDir(VideoURL);
                        headftp.ChDir(VideoURL);
                    }
                    else if (flag == 0)
                    {
                        branchftp.ChDir(ImageURL);
                        headftp.ChDir(ImageURL);
                    }
                    headftp.Put(fileFullName, fileguid); //上传文件
                    branchftp.Put(fileFullName, fileguid);
                }
                catch (Exception ex)
                {
                    fileguid = "1" + ex.Message;
                    IsSucceed = false;
                    IsUpload = false;
                    return;
                }
                //Thread BranchupThread = new Thread(UpBranch);
                //BranchupThread.Start();
            }
            else
            {
                try
                {
                    headftp = new FTPClient(HEAD_NAS_IP, "", HEAD_NAS_USERNAME, HEAD_NAS_PASSWORD, 21);//总店FTP
                    if (flag == 1)
                    {
                        headftp.ChDir(VideoURL);
                    }
                    else if (flag == 0)
                    {
                        headftp.ChDir(ImageURL);
                    }
                    headftp.Put(fileFullName, fileguid); //上传文件
                }
                catch (Exception ex)
                {
                    fileguid = "2" + ex.Message;
                    IsSucceed = false;
                    IsUpload = false;
                    return;
                }
            }
            string strArry = ",jpg,bmp,gif,png,flv,wmv,mp4,avi,rmvb,f4v,mov";
            int intjudge = strArry.IndexOf("," + strsuffix + ",");
            //branchftp.ChDir(firstURL);
            //headftp.ChDir(firstURL);
            if (intjudge >= 0)
            {
                if (!Thumbnail())
                {
                    try
                    {
                        string uri = @"ftp://" + NAS_IP + "/" + ImageURL + fileguid;
                        System.Net.FtpWebRequest reqFTP;
                        reqFTP = (FtpWebRequest)FtpWebRequest.Create(new Uri(uri));
                        reqFTP.UseBinary = true;
                        if (ishead)
                        {
                            reqFTP.Credentials = new NetworkCredential(NAS_USERNAME, NAS_PASSWORD);
                        }
                        else
                        {
                            reqFTP.Credentials = new NetworkCredential(HEAD_NAS_USERNAME, HEAD_NAS_PASSWORD);
                        }
                        //reqFTP.Method = WebRequestMethods.Ftp.GetFileSize;
                        try
                        {
                            //WebResponse Sizeresponse = reqFTP.GetResponse();
                            reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;
                            WebResponse response = reqFTP.GetResponse();
                            //Sizeresponse.Close();
                            response.Close();
                            IsSucceed = false;
                        }
                        catch (WebException ex)
                        {
                            fileguid = "3" + ex.Message;
                            IsSucceed = false;
                            IsUpload = false;
                            return;
                        }
                        //reqFTP.Method = WebRequestMethods.Ftp.DeleteFile;

                    }
                    catch (Exception ex)
                    {
                        fileguid = "4" + ex.Message;
                        //MessageBox.Show("文件上传失败后删除文件失败！", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                        IsSucceed = false;
                        IsUpload = false;
                        return;
                    }
                }
                else
                {
                    IsSucceed = true;
                }
            }
            else
            {
                IsSucceed = false;
            }
        }



        #endregion

        #region 分店上传
        private void UpBranch()
        {
            branchftp = new FTPClient(NAS_IP, "", NAS_USERNAME, NAS_PASSWORD, 21);//分店FTP
            if (flag == 1)
            {
                branchftp.ChDir(VideoURL);
            }
            else if (flag == 0)
            {
                branchftp.ChDir(ImageURL);
            }
            branchftp.Put(fileFullName, fileguid);
        }
        #endregion

        #region 生成缩略图方法
        public bool Thumbnail()
        {
            try
            {
                string pathImageFrom = "";
                if (flag == 1)
                {
                    pathImageFrom = previewfullName;
                }
                else if (flag == 0)
                {
                    pathImageFrom = fileFullName;
                }
                //生成缩略图
                if (GenThumbnail(pathImageFrom, 300, 170))
                {
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                fileguid = "5" + ex.Message;
                IsSucceed = false;
                IsUpload = false;
                return false;
            }
        }
        #endregion

        #region 生成缩略图
        /// <summary>
        /// 生成缩略图
        /// </summary>
        /// <param name="originalImagePath">源图路径（物理路径）</param>
        /// <param name="thumbnailPath">缩略图路径（物理路径）</param>
        /// <param name="width">缩略图宽度</param>
        /// <param name="height">缩略图高度</param>
        /// <param name="mode">生成缩略图的方式</param> 
        public bool GenThumbnail(string pathImageFrom, int width, int height)
        {
            Image imageFrom = null;
            try
            {
                imageFrom = Image.FromFile(pathImageFrom);
            }
            catch(Exception ex)
            {
                fileguid = "6" + ex.Message;
                imageFrom = null;
                IsSucceed = false;
                IsUpload = false;
                //MessageBox.Show("图片格式无效或图片不存在！", "系统提示", MessageBoxButtons.OK, MessageBoxIcon.Information);
                //uiContext.Post(UpdateUI, " ");
                return false;
            }
            if (imageFrom == null)
            {
                return false;
            }
            // 源图宽度及高度 
            int imageFromWidth = imageFrom.Width;
            int imageFromHeight = imageFrom.Height;
            // 生成的缩略图实际宽度及高度 
            int bitmapWidth = width;
            int bitmapHeight = height;
            // 生成的缩略图在上述"画布"上的位置 
            int X = 0;
            int Y = 0;
            // 根据源图及欲生成的缩略图尺寸,计算缩略图的实际尺寸及其在"画布"上的位置 
            if (bitmapHeight * imageFromWidth > bitmapWidth * imageFromHeight)
            {
                //bitmapHeight = imageFromHeight * width / imageFromWidth;
                Y = (height - bitmapHeight) / 2;
            }
            else
            {
                //bitmapWidth = imageFromWidth * height / imageFromHeight;
                X = (width - bitmapWidth) / 2;
            }
            // 创建画布 
            Bitmap bmp = new Bitmap(width, height);
            Graphics g = Graphics.FromImage(bmp);
            // 用白色清空    
            g.Clear(Color.White);
            // 指定高质量的双三次插值法。执行预筛选以确保高质量的收缩。此模式可产生质量最高的转换图像。 
            g.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
            //// 指定高质量、低速度呈现。 
            g.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.HighQuality;
            // 在指定位置并且按指定大小绘制指定的 Image 的指定部分。 
            g.DrawImage(imageFrom, new Rectangle(X, Y, bitmapWidth, bitmapHeight), new Rectangle(0, 0, imageFromWidth, imageFromHeight), GraphicsUnit.Pixel);
            try
            {
                byte[] bsThumbnailImage = ImageToStream(bmp);
                //uiContext.Post(UpdateUI, "缩略图生成完成！");
                int USERID = userid;
                string USERNAME = username;
                int BRANCH_ID = branchid;
                string FILE_NAME = fileName;
                string URL = "";
                string PreFileName = "";
                if (previewfullName != null)
                {
                    PreFileName = previewfullName.Substring(previewfullName.LastIndexOf(@"\") + 1);
                }
                //byte[] bsPreviewImage = null;
                if (flag == 1)
                {
                    URL = VideoURL;
                }
                else if (flag == 0)
                {
                    URL = ImageURL;

                }
                //uiContext.Post(UpdateUI, "缩略图上传中！");
                WebUpCilent server = new WebUpCilent();
                string newVideoImage = strGIud + "." + previewsuffix;
                string[] ParaStr = new string[] { strGIud, FILE_NAME, title, flag.ToString(), USERID.ToString(), USERNAME, BRANCH_ID.ToString(), URL, newVideoImage, PreFileName };
                if (server.UpFileRsout(ParaStr, bsThumbnailImage))
                {
                    server.InsertFile(strGIud, BRANCH_ID, ishead);
                    //uiContext.Post(UpdateUI, "缩略图上传成功！");
                    //uiContext.Post(UpdateUI, " ");
                    return true;
                }
                else
                {
                    return false;
                }
            }
            catch (Exception ex)
            {
                //uiContext.Post(UpdateUI, ex.Message.Substring(0, 4).ToString());
                fileguid = "7" + ex.Message;
                IsSucceed = false;
                IsUpload = false;
                return false;
            }
            finally
            {
                //显示释放资源 
                imageFrom.Dispose();
                imageFrom = null;
                bmp.Dispose();
                g.Dispose();
            }
        }

        public byte[] ImageToStream(Bitmap bmp)
        {
            System.IO.MemoryStream bstream = new System.IO.MemoryStream();
            bmp.Save(bstream, System.Drawing.Imaging.ImageFormat.Jpeg);
            bmp.Dispose();
            byte[] byteReturn = bstream.ToArray();
            bstream.Close();
            return byteReturn;
        }
        #endregion

        #region IObjectSafety 成员

        private const string _IID_IDispatch = "{00020400-0000-0000-C000-000000000046}";
        private const string _IID_IDispatchEx = "{a6ef9860-c720-11d0-9337-00a0c90dcaa9}";
        private const string _IID_IPersistStorage = "{0000010A-0000-0000-C000-000000000046}";
        private const string _IID_IPersistStream = "{00000109-0000-0000-C000-000000000046}";
        private const string _IID_IPersistPropertyBag = "{37D84F60-42CB-11CE-8135-00AA004BB851}";

        private const int INTERFACESAFE_FOR_UNTRUSTED_CALLER = 0x00000001;
        private const int INTERFACESAFE_FOR_UNTRUSTED_DATA = 0x00000002;
        private const int S_OK = 0;
        private const int E_FAIL = unchecked((int)0x80004005);
        private const int E_NOINTERFACE = unchecked((int)0x80004002);

        private bool _fSafeForScripting = true;
        private bool _fSafeForInitializing = true;


        public int GetInterfaceSafetyOptions(ref Guid riid, ref int pdwSupportedOptions, ref int pdwEnabledOptions)
        {
            int Rslt = E_FAIL;

            string strGUID = riid.ToString("B");
            pdwSupportedOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER | INTERFACESAFE_FOR_UNTRUSTED_DATA;
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForScripting == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_CALLER;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    Rslt = S_OK;
                    pdwEnabledOptions = 0;
                    if (_fSafeForInitializing == true)
                        pdwEnabledOptions = INTERFACESAFE_FOR_UNTRUSTED_DATA;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        public int SetInterfaceSafetyOptions(ref Guid riid, int dwOptionSetMask, int dwEnabledOptions)
        {
            int Rslt = E_FAIL;

            string strGUID = riid.ToString("B");
            switch (strGUID)
            {
                case _IID_IDispatch:
                case _IID_IDispatchEx:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_CALLER) &&
                         (_fSafeForScripting == true))
                        Rslt = S_OK;
                    break;
                case _IID_IPersistStorage:
                case _IID_IPersistStream:
                case _IID_IPersistPropertyBag:
                    if (((dwEnabledOptions & dwOptionSetMask) == INTERFACESAFE_FOR_UNTRUSTED_DATA) &&
                         (_fSafeForInitializing == true))
                        Rslt = S_OK;
                    break;
                default:
                    Rslt = E_NOINTERFACE;
                    break;
            }

            return Rslt;
        }

        #endregion
    }

    //    #region //接口

    //    [ComImport, Guid("00000118-0000-0000-C000-000000000046"), InterfaceType(ComInterfaceType.InterfaceIsIUnknown)]

    //    public interface IOleClientSite
    //    {

    //        void SaveObject();

    //        void GetMoniker(uint dwAssign, uint dwWhichMoniker, object ppmk);

    //        void GetContainer(out IOleContainer ppContainer);

    //        void ShowObject();

    //        void OnShowWindow(bool fShow);

    //        void RequestNewObjectLayout();

    //    }

    //    [ComImport, Guid("0000011B-0000-0000-C000-000000000046"), InterfaceTypeAttribute(ComInterfaceType.InterfaceIsIUnknown)]

    //    public interface IOleContainer
    //    {

    //        void EnumObjects([In, MarshalAs(UnmanagedType.U4)] int grfFlags,

    //        [Out, MarshalAs(UnmanagedType.LPArray)] object[] ppenum);

    //        void ParseDisplayName([In, MarshalAs(UnmanagedType.Interface)] object pbc,

    //        [In, MarshalAs(UnmanagedType.BStr)] string pszDisplayName,

    //        [Out, MarshalAs(UnmanagedType.LPArray)] int[] pchEaten,

    //        [Out, MarshalAs(UnmanagedType.LPArray)] object[] ppmkOut);

    //        void LockContainer([In, MarshalAs(UnmanagedType.I4)] int fLock);

    //    }
    //#endregion
}
